<template>
    <div>
      <!-- 面包屑 -->
      <el-breadcrumb separator-class="el-icon-arrow-right">
        <el-breadcrumb-item :to="{ path: '/welcome' }">首页</el-breadcrumb-item>
        <el-breadcrumb-item>权限管理</el-breadcrumb-item>
        <el-breadcrumb-item>角色列表</el-breadcrumb-item>
      </el-breadcrumb>
      <!-- 卡片视图 -->
      <el-card class="box-card">
        <el-button type="primary">添加角色</el-button>
        <!-- 角色列表表格 -->
        <el-table :data="rolesList" border stripe>
          <el-table-column type="expand">
            <template slot-scope="scope">
              <!-- 循环生成一级权限  scope.row.children:一级权限，内部包含二级和三级 -->
              <el-row :class="['bdbottom','center',i===0?'bdtop':'']" v-for="(item,i) in scope.row.children" :key="item.id">
                <!-- 展示一级权限 -->
                <el-col :span="8">
                  <el-tag>{{ item.authName }}</el-tag>
                  <i class="el-icon-caret-right"></i>
                </el-col>
                <!-- 嵌套二级和三级权限 -->
                <el-col :span="16">
                  <!-- 循环生成二级权限 item.children -->
                  <el-row class="center" :class="i===0?'':'bdtop'" v-for="(secondItem,i) in item.children">
                    <!-- 展示二级权限 -->
                    <el-col :span="8">
                      <el-tag type="success">{{ secondItem.authName }}</el-tag>
                      <i class="el-icon-caret-right"></i>
                    </el-col>
                    <!-- 嵌套三级权限 -->
                    <el-col :span="16">
                      <el-tag 
                      closable
                      @close="removeTag(scope.row,thirdItem.id)"
                      type="warning" 
                      :key="thirdItem.id"
                      v-for="thirdItem in secondItem.children">
                        {{ thirdItem.authName }}
                      </el-tag>
                    </el-col>
                  </el-row>
                </el-col>
              </el-row>
            </template>
          </el-table-column>
          <el-table-column label="#" type="index"></el-table-column>
          <el-table-column label="角色名称" prop="roleName"></el-table-column>
          <el-table-column label="角色描述" prop="roleDesc"></el-table-column>
          <el-table-column label="操作" width="290">
            <template slot-scope="scope">
              <el-button size="mini" type="primary" icon="el-icon-edit">编辑</el-button>
              <el-button size="mini" type="danger" icon="el-icon-delete">删除</el-button>
              <el-button @click="showSetRights(scope.row)" size="mini" type="warning" icon="el-icon-setting">分配权限</el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-card>
      <!-- 分配权限 -->
      <el-dialog
        @close="setRightsClose"
        title="分配权限"
        :visible.sync="setRightsDialogVisible"
        width="50%">
        <!-- data:绑定所有的数据  props：组件配置对象-->
        <el-tree 
        :default-checked-keys="defaultKeys"
        :data="rightsList" 
        show-checkbox 
        default-expand-all 
        node-key="id" 
        ref="tree"
        :props="defaultProps">
        </el-tree>
        <span slot="footer" class="dialog-footer">
          <el-button @click="setRightsDialogVisible = false">取 消</el-button>
          <el-button type="primary" @click="setRights">确 定</el-button>
        </span>
      </el-dialog>
    </div>
</template>

<script>
export default {
  data() {
    return {
      // 所有角色
      rolesList: [],
      // 控制分配权限对话框显示隐藏
      setRightsDialogVisible: false,
      // 所有权限
      rightsList: [],
      // 属性空间配置对象
      defaultProps: {
        // 配置将数据中每一项哪个字段渲染到页面
        label: 'authName'
      },
      // 设置默认选中
      defaultKeys: [],
      // 角色id
      roleId: 0
    }
  },

  created() {
    this.getRolesList()
  },

  methods: {
    // 获取角色列表数据
    async getRolesList () {
      const {data: res} = await this.$axios.get('roles')
      if(res.meta.status !== 200) return this.$message.error('获取数据失败')
      this.rolesList = res.data
    },
    // 删除权限
    removeTag (row,rightsId) {
      console.log(row)
      this.$confirm('此操作将永久删除该权限, 是否继续?', '提示', {
        confirmButtonText: '删除',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(async () => {
        // 当前用户id: row.id，权限id:rightsId
        const { data: res } = await this.$axios.delete(`roles/${row.id}/rights/${rightsId}`)
        if(res.meta.status !== 200) return this.$message.error('取消权限失败')
        this.$message.success('取消权限成功')
        row.children = res.data
      }).catch(() => {
        this.$message('以取消删除')       
      })
    },
    // 显示分配权限对话框
    async showSetRights (row) {
      this.roleId = row.id
      this.setRightsDialogVisible = true
      const {data: res} = await this.$axios.get('rights/tree')
      if(res.meta.status !== 200) return this.$message.error('获取数据失败')
      this.rightsList = res.data
      this.getAllKeys(row)
    },
    // 定义递归函数，通过递归获取所有的三级分类id
    getAllKeys (row) {
      // 如果row下面没有children了，也就代表是第三层，终止递归,将第三层每一项的id，push到defaultKeys
      if(!row.children) return this.defaultKeys.push(row.id)
      row.children.forEach(item=>{
        this.getAllKeys(item)
      })
    },
    // 监听关闭分配权限对话框
    setRightsClose () {
      this.defaultKeys = []
    },
    // 给用户分配权限
    async setRights () {
      // 发送请求
      // 1: 角色id
      // 2：所有授权的权限id （获取到所有勾选的权限id包括父级半选）
      // 获取所有的全选节点
      const keys = this.$refs.tree.getCheckedKeys()
      // 获取所有的半选节点
      const halfKeys = this.$refs.tree.getHalfCheckedKeys()
      const allKeys = [...keys,...halfKeys].join(',')
      // 准备好所需数据，发送请求
      const {data: res} = await this.$axios.post(`roles/${this.roleId}/rights`,{
        rids: allKeys
      })
      if(res.meta.status !== 200) return this.$message.error('更新失败')
      this.$message.success('更新成功')
      this.setRightsDialogVisible = false
      this.getRolesList()
    }
  }
};
</script>

<style scoped lang='less'>
.bdtop{
  border-top:1px solid #eee;
}
.bdbottom{
  border-bottom:1px solid #eee;
}
.el-tag {
  margin: 7px;
}

.center {
  display: flex;
  align-items: center;
}
</style>
